/* Copyright (c) [2024] [ylc]. Licensed under Apache-2.0 License. */
#include "TM1628.h"

mTMTypedef_t Tm1={0};

/*********************************************************/
//STB P50
//CLK P51
//DIO P11
static void IoInit(void) {
    IOHCON0 = 0;
    IOHCON1 = 0;
    P50 = 1;
    P51 = 1;
    P11 = 1;
    P1CON |= (1 << 1);
    P5CON |= (1 << 0) | (1 << 1);
    P1PH |= (1 << 1);
    P5PH |= ((1 << 0) | (1 << 1));

}

static void DelayUs(void) {
    u16 i;
    for (i = 0;i < 10;i++) {
        _nop_();
    }
}

static void DioH(void) {
    P1CON &= ~(1 << 1);
    P11 = 1;
}

static void DioL(void) {
    P1CON |= (1 << 1);
    P11 = 0;
}

static void ClkH(void) {
    P5CON &= ~(1 << 1);
    P51 = 1;
}

static void ClkL(void) {
    P5CON |= (1 << 1);
    P51 = 0;
}

static void StbH(void) {
    P5CON &= ~(1 << 0);
    P50 = 1;
}

static void StbL(void) {
    P5CON |= (1 << 0);
    P50 = 0;
}

static u8 ReadDio(void) {
    return P11;
}

static u8 ReadClk(void) {
    return P51;
}


/*********************************************************/

void tm_SendByte(mTMTypedef_t* tm, u8 _ucByte)
{
    u8 i;
       /*first bit0 */
    for (i = 0;i < 8;i++) {
        tm->CLK_L();
        if (_ucByte & 0x01) {
            tm->DIO_H();
        }
        else {
            tm->DIO_L();
        }
        tm->DelayUs();
        tm->CLK_H();
        tm->DelayUs();
        _ucByte >>= 1;
    }
    tm->DIO_H();
}

u8 tm_ReadByte(mTMTypedef_t* tm) {
    u8 i;
    u8 value;
    /*first bit0 */
    value = 0;
    for (i = 0;i < 8;i++) {
        value >>= 1;
        tm->CLK_L();
        tm->DelayUs();		//允许从机修改sda时间
        tm->CLK_H();	    //锁定DIO
        if (tm->READ_DIO()) {
            value |= 0x80;
        }
        tm->DelayUs();
    }
    return value;
}

void tm_SendCmd(mTMTypedef_t* tm, u8 cmd)  //只发送命令字节
{
    tm->STB_L();
    tm_SendByte(tm, cmd);
    tm->STB_H();
    tm->DelayUs();
}



//设备注册
void tm_device_init(mTMTypedef_t* tm)
{
    tm->InitPort = IoInit;
    tm->DelayUs = DelayUs;
    tm->DIO_H = DioH;
    tm->DIO_L = DioL;
    tm->CLK_H = ClkH;
    tm->CLK_L = ClkL;
    tm->STB_H = StbH;
    tm->STB_L = StbL;
    tm->READ_DIO = ReadDio;
    tm->READ_CLK = ReadClk;
}

void tm1628_init(void)
{
    tm_device_init(&Tm1);
    Tm1.InitPort();

    tm_SendCmd(&Tm1, TM_DISPLAY_MODE_6_11);
    tm_SendCmd(&Tm1, TM_DISPLAY_CTRL_14_16);
    tm1628_full_display(); 
}


void tm1628_clear(void)
{
    u8 i;
    tm_SendCmd(&Tm1, TM_DATA_WRITE_INC);
    Tm1.STB_L();
	tm_SendByte(&Tm1, TM_ADDRESS_C0);
    for (i = 0; i < 14; i++)
    {
        tm_SendByte(&Tm1, 0x00);
    }
    Tm1.STB_H();
    Tm1.DelayUs();
}


void tm1628_full_display(void)
{
    u8 i;
    tm_SendCmd(&Tm1, TM_DATA_WRITE_INC);
    Tm1.STB_L();
	tm_SendByte(&Tm1, TM_ADDRESS_C0);
    for (i = 0; i < 14; i++)
    {
        tm_SendByte(&Tm1, 0xFF);
    }
    Tm1.STB_H();
    Tm1.DelayUs();
}

void tm1628_refresh(void)
{
    u8 i;
    tm_SendCmd(&Tm1, TM_DATA_WRITE_INC);
	Tm1.STB_L();
    tm_SendByte(&Tm1, TM_ADDRESS_C0);

    for (i = 0; i < 14; i++){
        tm_SendByte(&Tm1, Tm1.reg.buf[i]);
    }
    Tm1.STB_H();
    Tm1.DelayUs();
}

void tm1628_read_key(void)			//读取5字节按键值并存入数组KEY[],从低字节、低位开始
{
    u8 i;
	Tm1.STB_L();
    tm_SendByte(&Tm1, TM_DATA_READ_INC);	            //发送读按键命令
	Tm1.DelayUs();
    for (i = 0;i < 5;i++) {
        Tm1.key[i] = tm_ReadByte(&Tm1);
    }
    Tm1.STB_H();
    Tm1.DelayUs();
}


